import collections
import json
import coin.strategy.mm.fastfeature.util as ffutil
from coin.strategy.mm.subscription import (get_subscription_key,
                                           FeedSubscriptionRequest,
                                           SubscriptionRequest)


def feed_sub_request_from_psub_map(psub_map, sub_key_not_none):
  dlist = collections.defaultdict(list)
  product_subkey_map = {}
  for product, sub_key_str in psub_map.items():
    if sub_key_str is None:
      assert not sub_key_not_none
      sub_key = get_subscription_key(product)
    else:
      sub_key = SubscriptionRequest.from_str(sub_key_str)
    dlist[sub_key].append(product)
    product_subkey_map[product] = sub_key
  feed_sub_request = FeedSubscriptionRequest()
  for sub_key, products in dlist.items():
    feed_sub_request.add_products(products, sub_key)
  return product_subkey_map, feed_sub_request


class FastFeatureFeedInfo(object):
  def __init__(self,
               *,
               psub_map,
               level_override_map,
               sub_key_not_none,
               bitmex_bbo_compress=False,
               okex_trade_min_qty=None,
               psub_map_feed_cache=None):
    self.psub_map = psub_map

    self.product_subkey_map, self.feed_sub_request =\
        feed_sub_request_from_psub_map(self.psub_map, sub_key_not_none)

    if psub_map_feed_cache is not None:
      _, self.feed_sub_request_feed_cache =\
          feed_sub_request_from_psub_map(psub_map_feed_cache, sub_key_not_none)
    else:
      self.feed_sub_request_feed_cache = None

    self.level_override_map = level_override_map
    self.bitmex_bbo_compress = bitmex_bbo_compress
    self.okex_trade_min_qty = okex_trade_min_qty

  def get_subscription_key(self, product):
    assert product in self.product_subkey_map, (product, self.product_subkey_map)
    return self.product_subkey_map[product]


def psub_map_from_subscriptions(subscriptions, as_of_time):
  psub_map = collections.OrderedDict()
  for subscription in subscriptions:
    symbol_dict = subscription['product']
    subscription_key = subscription['subscription_key']
    product = ffutil.product_from_symbol_dict(symbol_dict, as_of_time)
    psub_map[product] = subscription_key
  return psub_map


def from_file(feed_info_filepath, as_of_time):
  feed_info_obj = json.load(open(feed_info_filepath, 'r'))
  psub_map = psub_map_from_subscriptions(feed_info_obj['subscriptions'], as_of_time)
  psub_map_feed_cache = None
  if 'subscriptions_feed_cache' in feed_info_obj:
    psub_map_feed_cache = psub_map_from_subscriptions(feed_info_obj['subscriptions_feed_cache'],
                                                      as_of_time)

  level_override_map = collections.defaultdict(lambda: 10)
  for override in feed_info_obj.get('level_override', []):
    product = ffutil.product_from_symbol_dict(override, as_of_time)
    level_override_map[product] = override['level_override']

  bitmex_bbo_compress = feed_info_obj.get('bitmex_bbo_compress', False)

  okex_trade_min_qty = feed_info_obj.get('okex_trade_min_qty', None)

  return FastFeatureFeedInfo(psub_map=psub_map,
                             psub_map_feed_cache=psub_map_feed_cache,
                             level_override_map=level_override_map,
                             sub_key_not_none=True,
                             bitmex_bbo_compress=bitmex_bbo_compress,
                             okex_trade_min_qty=okex_trade_min_qty)
